﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;

namespace Xceed.Silverlight.Data
{
  internal class TakePagingEnumerator<T> : FetchPagingEnumerator<T> where T : RawDataItem
  {
    #region Constructor

    internal TakePagingEnumerator(
      IAsyncEnumerator childEnumerator,
      IContextualItemHelper<T> itemHelper,
      Func<int> pageSize )
      : base( childEnumerator, pageSize )
    {
      if( itemHelper == null )
        throw new ArgumentNullException( "itemHelper" );

      m_itemHelper = itemHelper;
    }

    #endregion

    protected override Page GetNextPage(
      DataSourceContext context,
      SourcePosition sourcePosition,
      long moveCount,
      int moveUnit,
      int pageSize )
    {
      // We must not use an ItemPosition if we cannot jump over the
      // starting item.  To avoid this, we convert the ItemPosition
      // into a SortPosition.
      if( ( Math.Abs( pageSize ) == 1 ) && ( sourcePosition is ItemPosition ) )
      {
        StartPosition startPosition = ( moveUnit > 0 ) ? StartPosition.After : StartPosition.Before;
        T startingItem = ( ( ItemPosition )sourcePosition ).Item as T;

        if( startingItem == null )
          throw new DataInternalException( "The specified ItemPosition must be a RawDataItem instance." );

        sourcePosition = SortPosition.Create( context, startingItem, startPosition, m_itemHelper );

        // The skipping counter and the actual move count will have to be adjusted since
        // the SortPosition created skips the starting item.
        return new Page( sourcePosition, 0, moveUnit );
      }
      else
      {
        return base.GetNextPage( context, sourcePosition, moveCount, moveUnit, pageSize );
      }
    }

    #region Private Fields

    private readonly IContextualItemHelper<T> m_itemHelper;

    #endregion
  }
}
